#include "StorageManager.h"
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>  // 添加这行
#include <iomanip>  // 添加这行

void printMenu()
{
    std::cout << "\n"
              << std::string(50, '=') << std::endl;
    std::cout << "🏗️  页式存储系统交互演示" << std::endl;
    std::cout << std::string(50, '=') << std::endl;
    std::cout << "1. 📊 查看缓存统计信息" << std::endl;
    std::cout << "2. 📋 列出所有表" << std::endl;
    std::cout << "3. 🏗️  创建新表" << std::endl;
    std::cout << "4. ➕ 插入记录" << std::endl;
    std::cout << "5. 🔍 查询记录" << std::endl;
    std::cout << "6. 🗑️  删除记录" << std::endl;
    std::cout << "7. 📄 获取页信息" << std::endl;
    std::cout << "8. 🔄 切换缓存策略" << std::endl;
    std::cout << "9. 📏 调整缓冲区大小" << std::endl;
    std::cout << "10. 💾 刷新所有页" << std::endl;
    std::cout << "11. 📈 运行性能测试" << std::endl;
    std::cout << "12. 🧹 清空缓存统计" << std::endl;
    std::cout << "13. 🔗 多表联查" << std::endl;
    std::cout << "0. 🚪 退出系统" << std::endl;
    std::cout << std::string(50, '=') << std::endl;
    std::cout << "请选择操作 (0-13): ";
}

void showCacheStats(MiniDB::StorageManager &sm)
{
    const auto &stats = sm.getCacheStats();
    std::cout << "\n📊 缓存统计信息:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "总请求数:     " << stats.total_requests << std::endl;
    std::cout << "缓存命中:     " << stats.cache_hits << std::endl;
    std::cout << "缓存未命中:   " << stats.cache_misses << std::endl;
    std::cout << "命中率:       " << std::fixed << std::setprecision(2)
              << stats.getHitRate() * 100 << "%" << std::endl;
    std::cout << "页读取数:     " << stats.pages_read << std::endl;
    std::cout << "页写入数:     " << stats.pages_written << std::endl;
    std::cout << "页替换数:     " << stats.replacements << std::endl;
}

void listTables(MiniDB::StorageManager &sm)
{
    auto table_names = sm.getTableNames();
    std::cout << "\n📋 数据库中的表:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    if (table_names.empty())
    {
        std::cout << "暂无表" << std::endl;
        return;
    }

    for (size_t i = 0; i < table_names.size(); ++i)
    {
        const std::string &table_name = table_names[i];
        size_t record_count = sm.getRecordCount(table_name);
        size_t table_size = sm.getTableSize(table_name);
        std::cout << (i + 1) << ". " << table_name
                  << " (记录数: " << record_count
                  << ", 大小: " << table_size << " bytes)" << std::endl;
    }
}

void createTable(MiniDB::StorageManager &sm)
{
    std::string table_name;
    std::cout << "\n🏗️  创建新表" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "请输入表名: ";
    std::cin >> table_name;

    if (sm.createTable(table_name))
    {
        std::cout << "✅ 表 '" << table_name << "' 创建成功!" << std::endl;
    }
    else
    {
        std::cout << "❌ 表 '" << table_name << "' 创建失败!" << std::endl;
    }
}

void insertRecord(MiniDB::StorageManager &sm)
{
    auto table_names = sm.getTableNames();
    if (table_names.empty())
    {
        std::cout << "\n❌ 没有可用的表，请先创建表!" << std::endl;
        return;
    }

    std::cout << "\n➕ 插入记录" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "可用表:" << std::endl;
    for (size_t i = 0; i < table_names.size(); ++i)
    {
        std::cout << (i + 1) << ". " << table_names[i] << std::endl;
    }

    std::cout << "请选择表 (输入表名): ";
    std::string table_name;
    std::cin >> table_name;

    if (!sm.tableExists(table_name))
    {
        std::cout << "❌ 表 '" << table_name << "' 不存在!" << std::endl;
        return;
    }

    int id;
    std::string data;
    std::cout << "请输入记录ID: ";
    std::cin >> id;
    std::cout << "请输入记录数据: ";
    std::cin.ignore(); // 清除换行符
    std::getline(std::cin, data);

    MiniDB::Record record(id, data);
    if (sm.insertRecord(table_name, record))
    {
        std::cout << "✅ 记录插入成功!" << std::endl;
    }
    else
    {
        std::cout << "❌ 记录插入失败!" << std::endl;
    }
}

void queryRecords(MiniDB::StorageManager &sm)
{
    auto table_names = sm.getTableNames();
    if (table_names.empty())
    {
        std::cout << "\n❌ 没有可用的表!" << std::endl;
        return;
    }

    std::cout << "\n🔍 查询记录" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "可用表:" << std::endl;
    for (size_t i = 0; i < table_names.size(); ++i)
    {
        std::cout << (i + 1) << ". " << table_names[i] << std::endl;
    }

    std::cout << "请选择表 (输入表名): ";
    std::string table_name;
    std::cin >> table_name;

    if (!sm.tableExists(table_name))
    {
        std::cout << "❌ 表 '" << table_name << "' 不存在!" << std::endl;
        return;
    }

    auto records = sm.getRecords(table_name);
    std::cout << "\n📋 表 '" << table_name << "' 中的记录:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    if (records.empty())
    {
        std::cout << "表为空" << std::endl;
        return;
    }

    for (size_t i = 0; i < records.size(); ++i)
    {
        const auto &record = records[i];
        if (!record.is_deleted)
        {
            std::cout << (i + 1) << ". ID: " << record.id
                      << ", Data: " << record.data << std::endl;
        }
    }
}

void performMultiTableJoin(MiniDB::StorageManager &sm)
{
    auto table_names = sm.getTableNames();
    if (table_names.size() < 2)
    {
        std::cout << "\n❌ 需要至少两个表才能进行多表联查!" << std::endl;
        std::cout << "当前只有 " << table_names.size() << " 个表" << std::endl;
        return;
    }

    std::cout << "\n🔗 多表联查" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "可用表:" << std::endl;
    for (size_t i = 0; i < table_names.size(); ++i)
    {
        std::cout << (i + 1) << ". " << table_names[i] << std::endl;
    }

    std::cout << "\n请输入要联查的表名 (用空格分隔): ";
    std::string input_line;
    std::getline(std::cin >> std::ws, input_line);

    std::vector<std::string> selected_tables;
    std::istringstream iss(input_line);
    std::string table_name;

    while (iss >> table_name)
    {
        if (!sm.tableExists(table_name))
        {
            std::cout << "❌ 表 '" << table_name << "' 不存在!" << std::endl;
            return;
        }
        selected_tables.push_back(table_name);
    }

    if (selected_tables.size() < 2)
    {
        std::cout << "❌ 需要至少选择两个表进行联查!" << std::endl;
        return;
    }

    // Perform the join
    auto join_results = sm.joinTables(selected_tables);

    std::cout << "\n📋 多表联查结果:" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    if (join_results.empty())
    {
        std::cout << "没有找到联查结果" << std::endl;
        return;
    }

    // Print header
    std::cout << "ID";
    for (const auto &table : selected_tables)
    {
        std::cout << "\t" << table;
    }
    std::cout << std::endl;

    std::cout << std::string(50, '-') << std::endl;

    // Print results
    for (const auto &result : join_results)
    {
        std::cout << result.id;
        for (const auto &table : selected_tables)
        {
            auto it = result.table_data.find(table);
            if (it != result.table_data.end())
            {
                std::cout << "\t" << it->second;
            }
            else
            {
                std::cout << "\t[无数据]";
            }
        }
        std::cout << std::endl;
    }

    std::cout << "\n✅ 联查完成，共找到 " << join_results.size() << " 条结果" << std::endl;
}

void deleteRecord(MiniDB::StorageManager &sm)
{
    auto table_names = sm.getTableNames();
    if (table_names.empty())
    {
        std::cout << "\n❌ 没有可用的表!" << std::endl;
        return;
    }

    std::cout << "\n🗑️  删除记录" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    std::cout << "可用表:" << std::endl;
    for (size_t i = 0; i < table_names.size(); ++i)
    {
        std::cout << (i + 1) << ". " << table_names[i] << std::endl;
    }

    std::cout << "请选择表 (输入表名): ";
    std::string table_name;
    std::cin >> table_name;

    if (!sm.tableExists(table_name))
    {
        std::cout << "❌ 表 '" << table_name << "' 不存在!" << std::endl;
        return;
    }

    int record_id;
    std::cout << "请输入要删除的记录ID: ";
    std::cin >> record_id;

    if (sm.deleteRecord(table_name, record_id))
    {
        std::cout << "✅ 记录删除成功!" << std::endl;
    }
    else
    {
        std::cout << "❌ 记录删除失败!" << std::endl;
    }
}

void showPageInfo(MiniDB::StorageManager &sm)
{
    std::cout << "\n📄 页信息查询" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    int page_id;
    std::cout << "请输入页ID: ";
    std::cin >> page_id;

    auto page = sm.getPage(page_id);
    if (page)
    {
        std::cout << "✅ 页 " << page_id << " 信息:" << std::endl;
        std::cout << "   页类型: " << (page->getPageType() == MiniDB::PageType::DATA_PAGE ? "数据页" : "索引页") << std::endl;
        std::cout << "   页大小: " << MiniDB::PAGE_SIZE << " bytes" << std::endl;
        std::cout << "   已使用: " << page->getUsedSpace() << " bytes" << std::endl;
        std::cout << "   剩余空间: " << page->getFreeSpace() << " bytes" << std::endl;
        std::cout << "   是否脏页: " << (page->isDirty() ? "是" : "否") << std::endl;
        std::cout << "   固定计数: " << page->getPinCount() << std::endl;
        sm.releasePage(page_id);
    }
    else
    {
        std::cout << "❌ 无法获取页 " << page_id << std::endl;
    }
}

void switchCachePolicy(MiniDB::StorageManager &sm)
{
    std::cout << "\n🔄 切换缓存策略" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "当前支持的策略:" << std::endl;
    std::cout << "1. LRU (Least Recently Used)" << std::endl;
    std::cout << "2. FIFO (First In First Out)" << std::endl;
    std::cout << "请选择策略 (1-2): ";

    int choice;
    std::cin >> choice;

    switch (choice)
    {
    case 1:
        sm.setReplacementPolicy(MiniDB::ReplacementPolicy::LRU);
        std::cout << "✅ 缓存策略已切换为 LRU" << std::endl;
        break;
    case 2:
        sm.setReplacementPolicy(MiniDB::ReplacementPolicy::FIFO);
        std::cout << "✅ 缓存策略已切换为 FIFO" << std::endl;
        break;
    default:
        std::cout << "❌ 无效选择!" << std::endl;
    }
}

void resizeBuffer(MiniDB::StorageManager &sm)
{
    std::cout << "\n📏 调整缓冲区大小" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "当前缓冲区大小: " << sm.getCacheStats().total_requests << " 帧" << std::endl;
    std::cout << "请输入新的缓冲区大小: ";

    size_t new_size;
    std::cin >> new_size;

    sm.resizeBuffer(new_size);
    std::cout << "✅ 缓冲区大小已调整为 " << new_size << " 帧" << std::endl;
}

void runPerformanceTest(MiniDB::StorageManager &sm)
{
    std::cout << "\n📈 运行性能测试" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;

    sm.resetCacheStats();

    // 创建测试表
    sm.createTable("perf_test");

    // 插入测试数据
    std::cout << "正在插入测试数据..." << std::endl;
    for (int i = 1; i <= 100; ++i)
    {
        MiniDB::Record record(i, "Performance test data " + std::to_string(i));
        sm.insertRecord("perf_test", record);
    }

    // 模拟随机访问模式
    std::cout << "正在模拟缓存访问..." << std::endl;
    for (int i = 0; i < 200; ++i)
    {
        int page_id = (rand() % 10) + 1; // 随机访问1-10页
        auto page = sm.getPage(page_id);
        if (page)
        {
            sm.releasePage(page_id);
        }
    }

    // 显示结果
    showCacheStats(sm);

    std::cout << "✅ 性能测试完成!" << std::endl;
}

int main()
{
    std::cout << "🚀 页式存储系统交互演示" << std::endl;
    std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;
    std::cout << "这是一个功能完整的页式存储系统演示程序" << std::endl;
    std::cout << "支持页分配、释放、读写操作和缓存管理" << std::endl;

    std::cout << "正在初始化StorageManager..." << std::endl;
    MiniDB::StorageManager storage_manager(20, MiniDB::ReplacementPolicy::LRU);
    std::cout << "StorageManager初始化完成" << std::endl;

    // 检查是否有之前保存的数据
    auto existing_tables = storage_manager.getTableNames();
    if (existing_tables.empty())
    {
        // 如果没有之前的数据，创建一些测试数据
        std::cout << "\n🔧 没有找到之前的数据库状态，创建测试数据..." << std::endl;
        storage_manager.createTable("demo_users");
        for (int i = 1; i <= 3; ++i)
        {
            MiniDB::Record record(i, "Demo User " + std::to_string(i));
            storage_manager.insertRecord("demo_users", record);
        }
        std::cout << "✅ 测试数据创建完成" << std::endl;
    }
    else
    {
        // 如果有之前的数据，显示恢复的信息
        std::cout << "\n📂 已从文件中恢复数据库状态" << std::endl;
        std::cout << "📋 恢复的表：" << std::endl;
        for (const auto& table_name : existing_tables)
        {
            size_t record_count = storage_manager.getRecordCount(table_name);
            std::cout << "   • " << table_name << " (" << record_count << " 条记录)" << std::endl;
        }
    }

    int choice;
    do
    {
        printMenu();
        std::cin >> choice;

        switch (choice)
        {
        case 1:
            showCacheStats(storage_manager);
            break;
        case 2:
            listTables(storage_manager);
            break;
        case 3:
            createTable(storage_manager);
            break;
        case 4:
            insertRecord(storage_manager);
            break;
        case 5:
            queryRecords(storage_manager);
            break;
        case 6:
            deleteRecord(storage_manager);
            break;
        case 7:
            showPageInfo(storage_manager);
            break;
        case 8:
            switchCachePolicy(storage_manager);
            break;
        case 9:
            resizeBuffer(storage_manager);
            break;
        case 10:
            storage_manager.flushAll();
            std::cout << "\n✅ 所有页已刷新到磁盘!" << std::endl;
            break;
        case 11:
            runPerformanceTest(storage_manager);
            break;
        case 12:
            storage_manager.resetCacheStats();
            std::cout << "\n✅ 缓存统计已清空!" << std::endl;
            break;
        case 13:
            performMultiTableJoin(storage_manager);
            break;
        case 0:
            std::cout << "\n👋 感谢使用页式存储系统，再见!" << std::endl;
            break;
        default:
            std::cout << "\n❌ 无效选择，请输入 0-13 之间的数字!" << std::endl;
        }

        if (choice != 0)
        {
            std::cout << "\n按回车键继续...";
            std::cin.ignore();
            std::cin.get();
        }

    } while (choice != 0);

    return 0;
}

